package com.lms.common.file.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lms.common.entity.TLmsFile;
import com.lms.common.file.api.utils.IFileUtil;
import com.lms.common.file.mapper.TLmsFileMapper;
import com.lms.common.file.service.ITLmsFileService;
import com.lms.common.web.service.impl.WrapperServiceImpl;
import com.lms.common.web.utils.CheckEntityResult;
import com.lms.resource.service.utils.SecurityUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@RequiredArgsConstructor
public class TLmsFileServiceServiceImpl extends WrapperServiceImpl<TLmsFileMapper, TLmsFile> implements ITLmsFileService {

    private final IFileUtil fileUtil;

    @Override
    public void download(HttpServletResponse response, String fileId) {
        // 根据fileId取出对应数据
        TLmsFile entity = this.getById(fileId);
        String fileName = entity.getFileName();
        // 去文件服务器中取文件
        // id就是存到文件服务器中的文件名
        InputStream inputStream = fileUtil.download(entity.getPath(), entity.getId());
//        BufferedInputStream bufferedInputStream = null;
//        OutputStream outputStream = null;
        try {

            IOUtils.copy(inputStream, response.getOutputStream());
            response.reset();
            // 设置ContentType，响应内容为二进制数据流，编码为utf-8，此处设定的编码是文件内容的编码
            response.setContentType("application/octet-stream;charset=utf-8");
            // 以（Content-Disposition: attachment; filename="filename.jpg"）格式设定默认文件名，设定utf编码，此处的编码是文件名的编码，使能正确显示中文文件名
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
//            //使用这个buffereInputStream 为了防止大文件内存溢出
//            bufferedInputStream = new BufferedInputStream(inputStream);
//            outputStream = response.getOutputStream();
//            //每次取出5M
//            byte[] buffer = new byte[1024 * 1024 * 5];
//            int len;
//            while ((len = bufferedInputStream.read(buffer)) != -1) {
//                outputStream.write(buffer, 0, len);
//            }
        } catch (IOException e) {
            log.error("文件下载失败！", e);
        } finally {
            if (inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("流关闭异常", e);
                }
            }
        }
    }

    @Override
    public CheckEntityResult beforeUpdate(TLmsFile entity, Serializable id) {
        entity.setCreateTime(LocalDateTime.now());
        entity.setCreateBy(SecurityUtil.getUserName());
        return CheckEntityResult.getInstance();
    }

    @Override
    public CheckEntityResult beforeInsert(TLmsFile entity) {
        entity.setCreateTime(LocalDateTime.now());
        entity.setCreateBy(SecurityUtil.getUserName());
        return CheckEntityResult.getInstance();
    }

    @Transactional
    @Override
    public String update(MultipartFile uploadFile, String businessId, String businessType, String businessColumn) {
        // 获取文件真实名称
        String fileName = uploadFile.getOriginalFilename();
        // 判断下fileId是否存在，存在的话则进行更新操作，并且服务器的文件是先删后插
        QueryWrapper<TLmsFile> params = new QueryWrapper<>();
        params.eq("business_id", businessId);
        params.eq("business_type", businessType);
        params.eq("business_column", businessColumn);
        List<TLmsFile> files = this.baseMapper.selectList(params);
        TLmsFile entity = new TLmsFile();

        if (!files.isEmpty()) {
            entity = files.get(0);
            // 删除服务器中的旧文件
            fileUtil.delete(entity.getPath(), entity.getFileName());
        } else {
            entity.setBusinessColumn(businessColumn);
            entity.setBusinessId(businessId);
            entity.setBusinessType(businessType);
        }
        entity.setFileName(fileName);
        this.saveEntity(entity);
        return null;
    }

    @Override
    public IPage<?> queryMapper(Page<TLmsFile> page, Map<String, Object> p) {
        return null;
    }
}
